package com.bankcomm.luafuction;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.Map.Entry;

import org.keplerproject.luajava.LuaException;
import org.keplerproject.luajava.LuaObject;
import org.keplerproject.luajava.LuaState;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.JsonPrimitive;
import com.rytong.tools.ui.Component;
import com.rytong.tools.utils.Utils;

public class LuaJson {

	LuaObject jsonObject = null;
	// LuaObject luaValue = null;
	TreeMap map_ = null;
	Object collectionObject;

	public LuaJson() {
		try {
			Component.LUASTATE.pushObjectValue(this);
			Component.LUASTATE.setGlobal("luajson");
			final String luahead = "json = {}; ";
			final String luafc1 = "function json:objectFromJSON(json) local a1 = luajson:objectFromJSON(json) return a1; end;";
			final String luafc2 = "function json:jsonFromObject(object) local a1 = luajson:jsonFromObject(object) return a1; end;";
			Component.LUASTATE.gc(LuaState.LUA_GCCOLLECT, 0);
			Component.LUASTATE.LdoString(luahead.concat(luafc1).concat(luafc2));
		} catch (LuaException e) {
			// TODO Auto-generated catch block
			Utils.printException(e);
		}
	}

	public Object objectFromJSON(Object json) {
		if (null == json)
			return "";
		String jsonData = "";
		if (json instanceof String)
			jsonData = (String) json;
		JsonParser jp = new JsonParser();
		JsonElement jsonE = jp.parse(jsonData);
		return pushJSONToTable(null, jsonE, false);
	}

	public Object jsonFromObject(Object object) {
		if (object instanceof LuaObject)
			jsonObject = (LuaObject) object;
		// map_ = new TreeMap();
		// Gson gson = new Gson();
		// String jsonString = gson.toJson(map_);
		return pushTableToJSON();
	}

	private Object getLastCollection(Object o) {
		if (o instanceof TreeMap) {
			TreeMap treeMap = (TreeMap) o;
			if (!treeMap.isEmpty()) {
				Object lastKey = treeMap.lastKey();
				Object lastValue = treeMap.get(lastKey);
				if (lastValue instanceof TreeMap) {
					collectionObject = lastValue;
					getLastCollection(lastValue);
				} else if (lastValue instanceof ArrayList) {
					collectionObject = lastValue;
					getLastCollection(lastValue);
				} else {
					return collectionObject;
				}
			}
		} else if (o instanceof ArrayList) {
			ArrayList arrayList = (ArrayList) o;
			Object valueObject = arrayList.get(arrayList.size() - 1);
			collectionObject = valueObject;
			getLastCollection(valueObject);
		}
		return collectionObject;
	}

	private String pushTableToJSON() {
		String result = "";
		try {
			Component.LUASTATE.pushNil();
			result = result.concat("{");
			while (Component.LUASTATE.next(-2) != 0) {
				String luaValue = null;
				String luaKey = null;
//				int key_type = -1;
				if (Component.LUASTATE.type(-2) == Component.LUASTATE.LUA_TNUMBER) {
//					key_type = 0;
					luaKey = String.valueOf((int) Component.LUASTATE
							.toNumber(-2));
				} else if (Component.LUASTATE.type(-2) == Component.LUASTATE.LUA_TSTRING) {
//					luaKey = "\"" + Component.LUASTATE.toString(-2) + "\"";
					luaKey = Component.LUASTATE.toString(-2);
				}
				
				luaKey = "\"" + luaKey + "\"";
				
				if (Component.LUASTATE.type(-1) == Component.LUASTATE.LUA_TTABLE) {
					luaValue = pushTableToJSON();
//					result += luaValue + ",";
				} else {
					if (Component.LUASTATE.type(-1) == Component.LUASTATE.LUA_TNUMBER) {
//						luaValue = Double.toString(Component.LUASTATE
//								.toNumber(-1));
						luaValue = String.valueOf((int)Component.LUASTATE.toNumber(-1));
					} else if (Component.LUASTATE.type(-1) == Component.LUASTATE.LUA_TSTRING) {
						luaValue = "\"" + Component.LUASTATE.toString(-1)
								+ "\"";
					}
//					if (key_type != 0) {
//						result += luaKey + ":" + luaValue + ",";
//					} else {
//						result += luaValue + ",";
//					}
				}
				
				result += luaKey + ":" + luaValue + ",";
				
				Component.LUASTATE.pop(1);
			}
			
			if(result.endsWith(",")){
				result = result.substring(0, result.length() - 1);
			}
			
			result = result.concat("}");
		} catch (Exception e) {
			Utils.printException(e);
		}
		return result;
	}

	private Object putCollectionForMapvalue(Object collection, Object key,
			Object value) {
		if (key == null || value == null) {
			return collection;
		}
		TreeMap submap = new TreeMap();
		if (collection instanceof TreeMap) {
			((TreeMap) collection).put(key, submap);
		} else if (collection instanceof ArrayList) {
			submap.put(collection, value);
			((ArrayList) collection).add(submap);
		}
		return collection;
	}

	private Object putCollectionForArrayvalue(Object collection, Object key,
			Object value) {
		if (key == null || value == null) {
			return collection;
		}
		if (collection instanceof TreeMap) {
			((TreeMap) collection).put(key, value);
		} else if (collection instanceof ArrayList) {
			TreeMap submap = new TreeMap();
			submap.put(key, value);
			((ArrayList) collection).add(submap);
		}
		return collection;
	}

	/**
	 * 
	 * @param table
	 *            element外的第一个table层
	 * @param element
	 * @param tableIsObject
	 *            表示传入的第一个参数是否是object转化的table
	 * @return
	 */
	private LuaObject pushJSONToTable(Object table, JsonElement element,
			boolean tableIsObject) {

		final LuaState luaState = Component.LUASTATE;
		LuaObject luaObject = null;
		if (null == table || !element.isJsonPrimitive()) {

			luaState.newTable();
		}
		luaObject = table == null ? luaState.getLuaObject(-1)
				: (LuaObject) table;

		try {

			if (element.isJsonArray()) {

				Utils.printOutToConsole("isJsonArray");
				int index = 1;
				final Iterator<JsonElement> iterator = ((JsonArray) element)
						.iterator();
				while (iterator.hasNext()) {

					Utils.printOutToConsole("isJsonArray index:" + index);
					luaState.pushNumber(index++);

					JsonElement jsonElement = iterator.next();
					pushJSONToTable(luaObject, jsonElement, false);

					luaState.setTable(-3);
				}
			} else if (element.isJsonObject()) {

				Utils.printOutToConsole("isJsonObject");
				JsonObject object = element.getAsJsonObject();
				Set<Map.Entry<String, JsonElement>> set = object.entrySet();
				Iterator<Entry<String, JsonElement>> iterator = set.iterator();
				while (iterator.hasNext()) {

					final Entry<String, JsonElement> entry = iterator.next();

					final String key = (String) entry.getKey();
					luaState.pushObjectValue(key);
					Utils.printOutToConsole("isJsonObject key:" + key);

					final JsonElement value = (JsonElement) entry.getValue();
					pushJSONToTable(luaObject, value, false);

					luaState.setTable(-3);
				}
			} else if (element.isJsonPrimitive()) {

				if (null == table) {

					luaState.pushNumber(1);
				}

				Utils.printOutToConsole("JsonPrimitive " + element.toString());
				final JsonPrimitive jp = (JsonPrimitive) element;
				if (jp.isBoolean()) {

					luaState.pushObjectValue(jp.getAsBoolean());
				} else if (jp.isString()) {

					luaState.pushObjectValue(jp.getAsString());
				} else if (jp.isNumber()) {

					luaState.pushObjectValue(jp.getAsNumber());
				}

				if (null == table) {

					luaState.setTable(-3);
				}
			}
		} catch (LuaException e) {

			Utils.printException(e);
		}
		return luaObject;

		// lua.newTable();
		// LuaObject primarytable = lua.getLuaObject(-1);
		// try {
		//
		// lua.pushObjectValue("aaa");
		// lua.pushObjectValue("111");
		// lua.setTable(-3);
		//
		// lua.pushObjectValue("bbb");
		// lua.pushObjectValue("222");
		// lua.setTable(-3);
		//
		// lua.pushObjectValue("ccc");
		// lua.newTable();
		// lua.pushObjectValue(1);
		// lua.pushObjectValue(2);
		// lua.setTable(-3);
		//
		// lua.pushNumber(2);
		// lua.pushNumber(3);
		// lua.setTable(-3);
		//
		// lua.pushNumber(3);
		// lua.pushNumber(5);
		// lua.setTable(-3);
		//
		// lua.pushNumber(4);
		// lua.pushNumber(7);
		// lua.setTable(-3);
		//
		// lua.setTable(-3);
		//
		// } catch (LuaException e) {
		// e.printStackTrace();
		// }
		//
		//
		// // 原始table对象，如果从外部传入的table存在，则里面的是外部的table，如果没有，则是在该方法中产生的table
		// LuaObject primarytable = null;
		// try {
		//
		// if (element.isJsonArray()) {
		// // 判断json数据是否是json数组
		// // 不管json元素是数组或者object，都以table包裹形式组装数据
		// Component.LUASTATE.newTable();
		// LuaObject tabletemp = Component.LUASTATE.getLuaObject(-1);
		// Component.LUASTATE.pop(1);
		//
		// if (null != table) {
		// primarytable = (LuaObject) table;
		// } else {
		// primarytable = tabletemp;
		// }
		// if (null != table) {
		// // 如果外部是一个table层，且这一层也是数组类型
		// primarytable.push();
		// Component.LUASTATE.pushString("");
		// Component.LUASTATE.pushObjectValue(tabletemp);
		// Component.LUASTATE.setTable(-3);
		// Component.LUASTATE.pop(1);
		// }
		// Iterator<JsonElement> iterator = ((JsonArray) element).iterator();
		// while (iterator.hasNext()) {
		// tabletemp = pushJSONToTable(tabletemp, iterator.next(), false);
		// }
		// } else if (element.isJsonObject()) {
		// // 判断json数据是否是json object
		// if (!tableIsObject) {
		// // 如果该参数为假，表示上层元素不是object类型
		// Component.LUASTATE.newTable();
		// primarytable = Component.LUASTATE.getLuaObject(-1);
		// Component.LUASTATE.pop(1);
		// } else {
		// primarytable = (LuaObject) table;
		// }
		//
		// primarytable.push();
		//
		// JsonObject object = element.getAsJsonObject();
		// Set<Map.Entry<String, JsonElement>> set = object.entrySet();
		// Iterator<Entry<String, JsonElement>> iterator = set.iterator();
		// Entry entry = null;
		// String key = "";
		// JsonElement value = null;
		// JsonPrimitive jp = null;
		// JsonObject jo = null;
		// boolean b;
		// String s;
		// Number n;
		// LuaObject tableChild;
		// while (iterator.hasNext()) {
		// // 遍历object内的元素，查看相应的键名和键值
		// entry = iterator.next();
		// key = (String) entry.getKey();
		// Component.LUASTATE.pushObjectValue(key);
		// value = (JsonElement) entry.getValue();
		// if (value.isJsonPrimitive()) {
		// // 如果键值为原始类型
		// jp = (JsonPrimitive) value;
		// if (jp.isBoolean()) {
		// b = jp.getAsBoolean();
		// Component.LUASTATE.pushObjectValue(b);
		// } else if (jp.isString()) {
		// s = jp.getAsString();
		// Component.LUASTATE.pushObjectValue(s);
		// } else if (jp.isNumber()) {
		// n = jp.getAsNumber();
		// Component.LUASTATE.pushObjectValue(n);
		// }
		// Component.LUASTATE.setTable(-3);
		// } else if (value.isJsonObject()) {
		// jo = value.getAsJsonObject();
		// Component.LUASTATE.newTable();
		// tableChild = Component.LUASTATE.getLuaObject(-1);
		// Component.LUASTATE.pop(1);
		// Component.LUASTATE.pushObjectValue(tableChild);
		// Component.LUASTATE.setTable(-3);
		// tableChild = pushJSONToTable(tableChild, jo, true);
		// } else if (value.isJsonArray()) {
		// Component.LUASTATE.newTable();
		// tableChild = Component.LUASTATE.getLuaObject(-1);
		// Component.LUASTATE.pop(1);
		// Component.LUASTATE.pushObjectValue(tableChild);
		// Component.LUASTATE.setTable(-3);
		//
		// Iterator<JsonElement> iteratorArray = ((JsonArray) value).iterator();
		// while (iteratorArray.hasNext()) {
		// tableChild = pushJSONToTable(tableChild, iteratorArray.next(),
		// false);
		// }
		// }
		// }
		// }
		// } catch (LuaException e) {
		// // TODO Auto-generated catch block
		// Utils.printException(e);
		// }

		// return primarytable;

	}

}
